package com.gzhryc.common.config;

import com.gzhryc.common.ClassTools;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Java配置文件读取类
 * @author 张浩
 */
public class PropertyTools {

	static PropertyTools tools;			//全局
	
	public static PropertyTools get() {
		return tools;
	}
	
	public static PropertyTools load(String filePath) throws IOException{
		tools = new PropertyTools(filePath);
		return tools;
	}
	
	public static PropertyTools load(File file) throws IOException{
		tools = new PropertyTools(file);
		return tools;
	}
	
	public static PropertyTools load(InputStream inStream) throws IOException{
		tools = new PropertyTools(inStream);
		return tools;
	}
	
	public static PropertyTools load(Properties properties) throws IOException{
		tools = new PropertyTools(properties);
		return tools;
	}
	
	public static <T> T setObject(Properties properties,T obj){
		try {
			for(Object key : properties.keySet()){
				String value = properties.getProperty(key.toString());
				if(key != null && StringUtils.isNotBlank(value)){
					ClassTools.setFieldValue(obj, key.toString(), value);
				} 
			}
			return obj;
		} catch (SecurityException e) {
			e.printStackTrace();
		} 
		return null;
	}
	
	public static PropertyTools build(Properties properties){
		return new PropertyTools(properties);
	}
	
	private Properties properties = new Properties();
	
	public PropertyTools(String filePath) throws IOException{
		File file = new File(filePath);
		InputStream inStream = null;
		try {
			if(file.exists()){
				inStream = new FileInputStream(file);
			}else{
				inStream = Class.class.getResourceAsStream(filePath);
			}
			BufferedReader bf = new BufferedReader(new InputStreamReader(inStream,"UTF-8"));
			properties.load(bf);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inStream != null){
				inStream.close();
			}
		}
	}
	
	public PropertyTools(File file) throws IOException{
		InputStream inStream = null;
		try {
			inStream = new FileInputStream(file);
			BufferedReader bf = new BufferedReader(new InputStreamReader(inStream,"UTF-8"));
			properties.load(bf);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inStream != null) {
				inStream.close();
			}
		}
	}
	
	public PropertyTools(InputStream inStream) throws IOException {
		BufferedReader bf = null;
		try {
			bf = new BufferedReader(new InputStreamReader(inStream,"UTF-8"));
			properties.load(bf);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (bf != null){
				bf.close();
			}
		}
	}
	
	public PropertyTools(Properties properties) {
		this.properties = properties;
	}
	
	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		if(this.properties != null) {
			this.properties.putAll(properties);
		}else {
			this.properties = properties;
		}
	}

	public Integer getInt(String name){
		return getInt(name,null);
	}
	
	public Integer getInt(String name,Integer defaultValue){
		String val = properties.getProperty(name);
		if(StringUtils.isBlank(val)){
			return defaultValue;
		}else{
			return Integer.valueOf(val.trim());
		}
	}

	public Long getLong(String name){
		return getLong(name,null);
	}
	
	public Long getLong(String name,Long defaultValue){
		String val = properties.getProperty(name);
		if(StringUtils.isBlank(val)){
			return defaultValue;
		}else{
			return Long.valueOf(val.trim());
		}
	}
	
	public Double getDouble(String name){
		return getDouble(name,null);
	}
	
	public Double getDouble(String name,Double defaultValue){
		String val = properties.getProperty(name);
		if(StringUtils.isBlank(val)){
			return defaultValue;
		}else{
			return Double.valueOf(val.trim());
		}
	}

	public Boolean getBoolean(String name){
		String val = properties.getProperty(name);
		if(StringUtils.isBlank(val)){
			return null;
		}else{
			return Boolean.valueOf(val.trim());
		}
	}
	
	public Boolean getBoolean(String name,Boolean defaultValue){
		String val = properties.getProperty(name);
		if(StringUtils.isBlank(val)){
			return defaultValue;
		}else{
			return Boolean.valueOf(val.trim());
		}
	}
	
	public String getString(String name){
		return getString(name,null);
	}
	
	public String getString(String name,String defaultValue){
		String val = properties.getProperty(name);
		if(StringUtils.isBlank(val)){
			return defaultValue;
		}else{
			return val.trim();
		}
	}
	
	public <T> T getObject(String name,Class<T> clazz){
		Pattern pat = Pattern.compile(name+"\\.([^\\.]+)");
		try {
			T obj = clazz.newInstance();
			for(Object key : properties.keySet()){
				String value = properties.getProperty(key.toString());
				if(key != null && StringUtils.isNotBlank(value)){
					Matcher mat = pat.matcher(key.toString());
					if(mat.find()){
						String gName = mat.group(1);
						ClassTools.setFieldValue(obj, gName, value);
					}
				}
			}
			return obj;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public <T> T getObject(T obj){
		try {
			for(Object key : properties.keySet()){
				String value = properties.getProperty(key.toString());
				if(key != null && StringUtils.isNotBlank(value)){
					ClassTools.setFieldValue(obj, key.toString(), value);
				} 
			}
			return obj;
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public <T> T getObject(Class<T> clazz){
		try {
			T obj = clazz.newInstance();
			for(Object key : properties.keySet()){
				String value = properties.getProperty(key.toString());
				if(key != null && StringUtils.isNotBlank(value)){
					ClassTools.setFieldValue(obj, key.toString(), value);
				} 
			}
			return obj;
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	public Properties getProperties(String name){
		Pattern pat = Pattern.compile("^"+name+"\\.(.*)$");
		Properties result = new Properties();
		for(Object key : properties.keySet()){
			String value = properties.getProperty(key.toString());
			if(key != null){
				Matcher mat = pat.matcher(key.toString());
				if(mat.find()){
					String gName = mat.group(1);
					result.setProperty(gName, value);
				}
			}
		}
		return result;
	}
}
